// Package api
// @Title api[简述该包的主要作用]
// @Description
// @Author  cnHuaShao
// @since v0.0.1
// @Version v1.0.0
// @Date 2024/6/21 16:39
// @Update 2024/6/21 16:39
package api

import (
	"FinancialManagement/src/base/baselog"
	"FinancialManagement/src/base/mess"
	"FinancialManagement/src/base/util"
	"FinancialManagement/src/business/common"
	"FinancialManagement/src/business/purchase"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"go.uber.org/zap"
	"net/http"
	"strings"
	"time"
)

// GetPurchaseListAll
// @Description: 获取全部采购列表，用于级联选择框使用
// @param c
func GetPurchaseListAll(c *gin.Context) {
	data, err := purchase.GetPurchaseListAll()
	if err != nil {
		c.JSON(http.StatusOK, mess.ResErrMess(910005119, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(data))
}

// DelPurchaseDetailItem
// @Description: 删除指定采购单明细信息
// @param c
func DelPurchaseDetailItem(c *gin.Context) {
	itemId := util.ToInt(c.DefaultPostForm("itemId", "0")) // 采购明细ID
	if err := purchase.DelPurchaseDetailItem(itemId); err != nil {
		baselog.Logger.Error("删除采购明细失败", zap.Error(err))
		c.JSON(http.StatusOK, mess.ResErrMess(910005117, "删除采购明细失败"))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(""))
}

// GetPurchaseList
// @Description: 获取采购单列表
// @param c
func GetPurchaseList(c *gin.Context) {
	purchaseDeparture := c.DefaultPostForm("purchaseDeparture", "")                      // 采购发车日期
	purchaseId := util.ToInt(c.DefaultPostForm("purchaseId", "0"))                       // 采购单
	purchaseVehicle := c.DefaultPostForm("purchaseVehicle", "")                          // 采购车辆
	purchaseUser := c.DefaultPostForm("purchaseUser", "")                                // 采购人员
	purchaseStatus := util.ToInt(c.DefaultPostForm("purchaseStatus", "0"))               // 采购状态 1暂存，2提交保存，3作废
	purchasePaymentStatus := util.ToInt(c.DefaultPostForm("purchasePaymentStatus", "0")) // 采购单付款状态，1未付款，2部分付款，3全部付款
	pageSize := util.ToInt(c.DefaultPostForm("pageSize", "10"))
	pageNumber := util.ToInt(c.DefaultPostForm("pageNumber", "1"))
	purchaseVehicle = strings.ToUpper(purchaseVehicle) // 转换车牌号为大写
	purchaseList, total, err := purchase.GetPurchaseList(purchaseDeparture, purchaseId, purchaseVehicle, purchaseUser, purchaseStatus, purchasePaymentStatus, pageSize, pageNumber)
	if err != nil {
		c.JSON(http.StatusOK, mess.ResErrMess(910005110, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(gin.H{
		"list":  purchaseList,
		"count": total,
	}))
}

// CreatePurchaseInfo
// @Description: 创建采购单
// @param c
func CreatePurchaseInfo(c *gin.Context) {
	purchaseVehicle := c.DefaultPostForm("purchaseVehicle", "")                               // 采购车辆
	purchaseUser := c.DefaultPostForm("purchaseUser", "")                                     // 采购人员
	purchaseStatus := util.ToInt(c.DefaultPostForm("purchaseStatus", "1"))                    // 采购状态 1暂存，2提交保存，3作废
	purchasePaymentStatus := util.ToInt(c.DefaultPostForm("purchasePaymentStatus", "1"))      // 采购单付款状态，1未付款，2部分付款，3全部付款
	purchaseFreight := util.ToInt(c.DefaultPostForm("purchaseFreight", "0"))                  // 采购运费
	purchaseDescribe := c.DefaultPostForm("purchaseDescribe", "")                             // 采购描述
	purchaseActualAmount := util.ToDecimal(c.DefaultPostForm("purchaseActualAmount", "0.00")) // 采购实际金额
	purchaseDeparture := c.DefaultPostForm("purchaseDeparture", "")                           // 采购出发日期
	purchaseInfo := purchase.PurchaseDetail{
		PurchaseVehicle:       strings.ToUpper(purchaseVehicle),     // 车牌号都转为大写 采购车辆
		PurchaseActualAmount:  purchaseActualAmount,                 // 采购实际金额
		PurchaseUser:          purchaseUser,                         // 采购人员
		PurchaseStatus:        purchaseStatus,                       // 采购状态 1暂存，2提交保存，3作废
		PurchasePaymentStatus: purchasePaymentStatus,                // 采购单付款状态，1未付款，2部分付款，3全部付款
		PurchaseFreight:       purchaseFreight,                      // 采购运费
		PurchaseDescribe:      purchaseDescribe,                     // 采购描述
		PurchaseDeparture:     common.CustomDate(purchaseDeparture), // 采购出发日期

		PurchaseTotalPrice:     decimal.NewFromInt(0), // 采购总价
		PurchaseUnitCost:       decimal.NewFromInt(0), // 采购单价（成本单价）
		PurchaseTotal:          decimal.NewFromInt(0), // 总数量，采购总斤数
		RemainSettlementAmount: decimal.NewFromInt(0), // 剩余结算总金额
		PurchaseCreateTime:     time.Now().Unix(),     // 采购创建时间
	}

	if err := purchaseInfo.CreatePurchaseInfo(); err != nil {
		baselog.Logger.Error("创建采购单失败", zap.Error(err))
		c.JSON(http.StatusOK, mess.ResErrMess(910005111, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(""))
}

// DelPurchaseInfo
// @Description:  逻辑删除采购单
// @param c
func DelPurchaseInfo(c *gin.Context) {
	purchaseId := util.ToInt(c.DefaultPostForm("purchaseId", "0")) // 采购单号
	if purchaseId == 0 {
		c.JSON(http.StatusOK, mess.ResErrMess(910005110, "请求参数缺失"))
		return
	}
	if err := purchase.DeletePurchaseInfo(purchaseId); err != nil {
		baselog.Logger.Error("删除采购单失败", zap.Error(err))
		c.JSON(http.StatusOK, mess.ResErrMess(910005112, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(""))
}

// UpdatePurchaseInfo
// @Description: 更新采购单
// @param c
func UpdatePurchaseInfo(c *gin.Context) {
	purchaseId := util.ToInt(c.DefaultPostForm("purchaseId", "0"))                         // 采购单号
	purchaseActualAmount := util.ToDecimal(c.DefaultPostForm("purchaseActualAmount", "0")) // 实际采购总金额
	purchaseVehicle := c.DefaultPostForm("purchaseVehicle", "")                            // 采购车辆
	purchaseDescribe := c.DefaultPostForm("purchaseDescribe", "")                          // 采购描述
	purchaseUser := c.DefaultPostForm("purchaseUser", "")                                  // 采购人
	purchasePaymentStatus := util.ToInt(c.DefaultPostForm("purchasePaymentStatus", "0"))   // 采购单付款状态，1未付款，2部分付款，3全部付款
	purchaseStatus := util.ToInt(c.DefaultPostForm("purchaseStatus", "0"))                 // 采购状态，1暂存，2提交保存，3作废
	purchaseFreight := util.ToInt(c.DefaultPostForm("purchaseFreight", "0"))               // 运费
	purchaseDeparture := c.DefaultPostForm("purchaseDeparture", "")                        // 出发日期

	if purchaseId == 0 {
		c.JSON(http.StatusOK, mess.ResErrMess(910005110, "请求参数缺失"))
		return
	}
	purchaseInfo, err := purchase.GetPurchaseInfo(purchaseId)
	if err != nil {
		return
	}
	purchaseInfo.PurchaseActualAmount = purchaseActualAmount                                   // 采购实际金额
	purchaseInfo.PurchaseVehicle = purchaseVehicle                                             // 车牌号都转为大写
	purchaseInfo.PurchaseDescribe = purchaseDescribe                                           // 采购描述
	purchaseInfo.PurchaseUser = purchaseUser                                                   // 采购人员
	purchaseInfo.PurchasePaymentStatus = purchasePaymentStatus                                 // 采购单付款状态，1未付款，2部分付款，3全部付款
	purchaseInfo.PurchaseStatus = purchaseStatus                                               // 采购状态，1暂存，2提交保存，3作废
	purchaseInfo.PurchaseFreight = purchaseFreight                                             // 运费
	purchaseInfo.PurchaseUnitCost = util.ToDecimal(c.DefaultPostForm("purchaseUnitCost", "0")) // 采购单价（成本单价）
	purchaseInfo.PurchaseDeparture = common.CustomDate(purchaseDeparture)                      // 出发日期

	remainingAmount := decimal.NewFromFloat(0) // 剩余结算金额
	settledAmount := decimal.NewFromFloat(0)   // 已结算金额

	for _, item := range purchaseInfo.Items {
		settledAmount = settledAmount.Add(item.SettlementAmount) // 叠加计算已结算金额
	}

	// 剩余结算金额=实际总金额-已结算金额
	remainingAmount = purchaseActualAmount.Sub(settledAmount)

	// 剩余结算金额
	purchaseInfo.RemainSettlementAmount = remainingAmount
	// 计算采购单价 （实际总金额+运费）/采购总数量 这是平均采购单价计算公式
	// 每种产品的采购单价 = 相同类别产品采购单价+(运费/采购总数量)
	if purchaseInfo.PurchaseTotal.Cmp(decimal.Zero) > 0 {
		purchaseInfo.PurchaseUnitCost = (purchaseActualAmount.Add(decimal.NewFromInt32(int32(purchaseFreight)))).Div(purchaseInfo.PurchaseTotal)
	} else {
		purchaseInfo.PurchaseUnitCost = decimal.NewFromFloat(0.0)
	}

	// 更新采购单
	err = purchaseInfo.UpdatePurchaseInfo()
	if err != nil {
		baselog.Logger.Error("更新采购单失败", zap.Error(err))
		c.JSON(http.StatusOK, mess.ResErrMess(910005112, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(""))
}

// AddPurchaseDetailItem
// @Description: 添加采购单详细采购明细
// @param c
func AddPurchaseDetailItem(c *gin.Context) {
	purchaseId := util.ToInt(c.DefaultPostForm("purchaseId", "0"))                               // 所属采购单
	productId := util.ToInt(c.DefaultPostForm("productId", "0"))                                 // 产品ID
	quantity, _ := decimal.NewFromString(c.DefaultPostForm("quantity", "0"))                     // 采购数量，斤数
	price, _ := decimal.NewFromString(c.DefaultPostForm("price", "0"))                           // 采购单价
	totalPrice, _ := decimal.NewFromString(c.DefaultPostForm("totalPrice", "0"))                 // 采购自动总价
	customerId := util.ToInt(c.DefaultPostForm("customerId", "0"))                               // 关联客户ID
	actualAmount, _ := decimal.NewFromString(c.DefaultPostForm("actualAmount", "0"))             // 实际采购金额
	itemDate := c.DefaultPostForm("itemDate", "")                                                // 采购日期
	irSettlementAmount, _ := decimal.NewFromString(c.DefaultPostForm("irSettlementAmount", "0")) // 待结算金额
	settlementAmount, _ := decimal.NewFromString(c.DefaultPostForm("settlementAmount", "0"))     // 结算金额
	settlementStatus := util.ToInt(c.DefaultPostForm("settlementStatus", "0"))                   // 结算状态，1已结算，2未结算，3部分结算
	itemType := util.ToInt(c.DefaultPostForm("itemType", "0"))                                   // 采购类型，1正常采购，2全额抵消，3部分抵消
	if purchaseId == 0 {
		c.JSON(http.StatusOK, mess.ResErrMess(910005110, "请求参数缺失"))
		return
	}

	// 改为前端计算
	// 结算状态，1已结算，2未结算，3部分结算
	/*settlementStatus := 2
	if settlementAmount.Equals(decimal.NewFromInt(0)) && settlementAmount.LessThan(actualAmount) {
		settlementStatus = 3
	} else if settlementAmount == actualAmount {
		settlementStatus = 1
	}*/
	// 采购单详细采购明细
	purchaseInfo := purchase.PurchaseDetailItem{
		PurchaseID:         purchaseId,                    // 所属采购单
		ProductID:          productId,                     // 产品ID
		Quantity:           quantity,                      // 采购数量，斤数
		Price:              price,                         // 采购单价
		TotalPrice:         totalPrice,                    // 采购自动总价
		CustomerID:         customerId,                    // 关联客户ID
		ActualAmount:       actualAmount,                  // 实际采购金额
		ItemDate:           purchase.CustomDate(itemDate), // 采购日期
		IrSettlementAmount: irSettlementAmount,            // 待结算金额
		SettlementAmount:   settlementAmount,              // 结算金额
		SettlementStatus:   settlementStatus,              // 结算状态，1已结算，2未结算，3部分结算
		ItemType:           itemType,                      // 采购类型，1正常采购，2全额抵消，3部分抵消

	}
	if err := purchaseInfo.CreatePurchaseDetailItem(); err != nil {
		baselog.Logger.Error("添加采购单详细采购明细失败", zap.Error(err))
		c.JSON(http.StatusOK, mess.ResErrMess(910005113, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(""))
}

// GetPurchaseInfo
// @Description: 获取指定采购单和其采购明细详情
// @param c
func GetPurchaseInfo(c *gin.Context) {
	purchaseId := util.ToInt(c.DefaultPostForm("purchaseId", "0"))
	if purchaseId == 0 {
		c.JSON(http.StatusOK, mess.ResErrMess(910005110, "请求参数缺失"))
		return
	}
	purchaseInfo, err := purchase.GetPurchaseInfo(purchaseId)
	if err != nil {
		baselog.Logger.Error("采购单详情获取失败", zap.Error(err))
		c.JSON(http.StatusOK, mess.ResErrMess(910005114, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(purchaseInfo))
}

// UpdatePurchaseDetailItem
// @Description: 更新指定采购明细
// @param c
func UpdatePurchaseDetailItem(c *gin.Context) {
	itemId := util.ToInt(c.DefaultPostForm("itemId", "0"))                         // 采购明细ID
	purchaseId := util.ToInt(c.DefaultPostForm("purchaseId", "0"))                 // 所属采购单
	quantity := util.ToDecimal(c.DefaultPostForm("quantity", "0"))                 // 采购数量，斤数
	price := util.ToDecimal(c.DefaultPostForm("price", "0"))                       // 采购单价
	totalPrice := quantity.Mul(quantity)                                           // 采购自动总价
	actualAmount := util.ToDecimal(c.DefaultPostForm("actualAmount", "0"))         // 实际采购金额
	settlementAmount := util.ToDecimal(c.DefaultPostForm("settlementAmount", "0")) // 已结算金额
	irSettlementAmount := actualAmount.Sub(settlementAmount)                       // 计算剩余结算金额
	settlementStatus := 2                                                          // 结算状态，1已结算，2未结算，3部分结算
	if irSettlementAmount.Equals(decimal.NewFromInt(0)) {
		settlementStatus = 1
	} else if irSettlementAmount.GreaterThan(decimal.NewFromInt(0)) && !settlementAmount.Equals(decimal.NewFromInt(0)) {
		settlementStatus = 3
	}

	if itemId == 0 {
		c.JSON(http.StatusOK, mess.ResErrMess(910005110, "请求参数缺失"))
		return
	}
	// 采购明细
	purchaseInfo := purchase.PurchaseDetailItem{
		ItemID:             itemId,
		PurchaseID:         purchaseId,
		Quantity:           quantity,
		Price:              price,
		TotalPrice:         totalPrice,
		ActualAmount:       actualAmount,
		SettlementAmount:   settlementAmount,
		IrSettlementAmount: irSettlementAmount,
		SettlementStatus:   settlementStatus,
	}
	if err := purchaseInfo.UpdatePurchaseDetailItem(); err != nil {
		baselog.Logger.Error("采购单详细采购明细修改失败", zap.Error(err))
		c.JSON(http.StatusOK, mess.ResErrMess(910005115, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(""))
}
